import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Properties;

public class DBUtils {
//    private final String JDBC_URL = "jdbc:mysql://localhost:3306/manger";
//    private final String USERNAME = "root";
//    private final String PASSWORD = "";
    private Connection conn;
    private PreparedStatement ps;

    /**
     * 传入SQL语句对查询操作进行处理
     * @param sql
     * @param handler
     * @param objects
     * @return
     * @param <E>
     * @throws SQLException
     * @throws ClassNotFoundException
     */
    public <E> List<E> selectSql(String sql , Handler<E> handler, Objects...objects) throws SQLException, ClassNotFoundException {
        getPrepared(sql);
        setPar(objects);
        ResultSet resultSet = ps.executeQuery();
        return handler.handle(resultSet);
    }

    /**
     * 传入SQL语句对增删改操作进行解析
     * @param sql
     * @param objects
     * @return
     * @throws SQLException
     * @throws ClassNotFoundException
     */
    public int updateSql(String sql ,Objects...objects) throws SQLException, ClassNotFoundException {
        getPrepared(sql);
        setPar(objects);
        return ps.executeUpdate();
    }

    /**
     * 解析传入的占位符并将其替换为实际的属性字段
     * @param objects
     * @throws SQLException
     */
    private void setPar(Objects...objects) throws SQLException {
        for (int i = 0; i < objects.length; i++) {
            ps.setObject(i + 1,objects[i]);
        }
    }

    /**
     * 获取数据库连接
     * @throws ClassNotFoundException
     * @throws SQLException
     */
    private void getCollect() throws ClassNotFoundException, SQLException {
        if (conn == null) {
            Properties properties = new Properties();
            try {
                properties.load(new FileInputStream("JDBC/JDBC9.28/io/druid.properties"));
                DataSource da = DruidDataSourceFactory.createDataSource(properties);
                conn = da.getConnection();;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }

    /**
     * 执行SQL语句
     * @param sql
     * @throws SQLException
     * @throws ClassNotFoundException
     */
    private void getPrepared(String sql) throws SQLException, ClassNotFoundException {
        getCollect();
        ps = conn.prepareStatement(sql);
    }

    public void close () throws SQLException {
        if (ps != null && !ps.isClosed()) {
            ps.close();
            ps = null;
        }
        if (conn != null && !conn.isClosed()) {
            conn.close();
            conn = null;
        }
    }
}

class Test{
    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        String sql = "select * from operation_log";
        DBUtils db = new DBUtils();
        List<Log> select = db.selectSql(sql, new Handler<Log>() {
            @Override
            public List<Log> handle(ResultSet set) throws SQLException {
                List<Log> list = new ArrayList<>();
                while (set.next()) {
                    Log log = new Log();
                    log.setLogId(set.getInt("log_id"));
                    log.setDescription(set.getString("description"));
                    log.setOperationTime(set.getTimestamp("operation_time"));
                    list.add(log);
                }
                return list;
            }
        });
        select.forEach(System.out::println);
    }
}
